package org.bee.check;


import org.bee.check.model.CheckResult;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

/**
 * 常用校验工具类
 */
public class ModelCheck {
    /**
     * 检查对象的字段是否符合约束条件
     * @param object 待检查的对象
     * @return 检查结果
     */
    public static CheckResult check(Object object){
        CheckResult result = CheckResult.success();
        Class<?> aClass = object.getClass();
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {
            field.setAccessible(true);
            Object value = null;
            try {
                value = field.get(object);
            } catch (IllegalAccessException e) {
                throw new RuntimeException(e);
            }

            // 检查是否被@NotNull注解标记，并且值为空或者空字符串
            if (field.isAnnotationPresent(NotNull.class)) {
                if(null==value||"".equals(value)){
                    result = CheckResult.fail();
                    result.setMsg(field.getName()+"不能为空");
                    return result;
                }
            }

            // 检查是否被@Regex注解标记，并且值不匹配正则表达式
            if(field.isAnnotationPresent(Regex.class)){
                Regex annotation = field.getAnnotation(Regex.class);
                String regex = annotation.value();
                Pattern pattern = Pattern.compile(regex);
                if(!pattern.matcher((String) value).matches()){
                    result = CheckResult.fail();
                    result.setMsg(field.getName()+"的值不匹配正则表达式");
                    if(null!=annotation.msg()&& !annotation.msg().isEmpty()){
                        result.setMsg(annotation.msg());
                    }
                    return result;
                }
            }

            // 检查是否被@Length注解标记，并且字符串长度不符合范围
            if(field.isAnnotationPresent(Length.class)){
                Length annotation = field.getAnnotation(Length.class);
                int min = annotation.min();
                int max = annotation.max();
                String stringValue = (String) value;
                if(null==stringValue){
                    stringValue = "";
                }
                int length = stringValue.length();
                if(length<min||length>max){
                    result = CheckResult.fail();
                    result.setMsg(field.getName()+"的长度不符合要求，最小长度为"+min+"，最大长度为"+max);
                    if(null!=annotation.msg()&& !annotation.msg().isEmpty()){
                        result.setMsg(annotation.msg());
                    }
                    return result;
                }
            }
            // 检查是否被@Enums注解标记，并且值不在枚举范围内
            if (field.isAnnotationPresent(Enums.class)) {
                Enums annotation = field.getAnnotation(Enums.class);
                Class<? extends Enum<?>> clazz = (Class<? extends Enum<?>>) annotation.value();
                try {
                    // 获取枚举类的所有实例
                    Enum<?>[] enumConstants = clazz.getEnumConstants();
                    // 获取 getCode 方法
                    Method getCodeMethod = clazz.getMethod("getCode");
                    // 使用 List 存储所有的 code 值
                    List<Object> codeList = new ArrayList<>();
                    for (Enum<?> enumConstant : enumConstants) {
                        Object code = getCodeMethod.invoke(enumConstant);
                        codeList.add(code);
                    }
                    // 检查 value 是否存在于 Map 中
                    if (codeList.contains(String.valueOf(value))) {
                        result = CheckResult.success();
                    }else{
                        result = CheckResult.fail();
                        result.setMsg(field.getName()+"的值不在枚举类"+codeList+"中");
                        if(null!=annotation.msg()&& !annotation.msg().isEmpty()){
                            result.setMsg(annotation.msg());
                        }
                    }
                    return result;
                    // 继续执行后续逻辑
                } catch (NoSuchMethodException e) {
                    result = CheckResult.fail();
                    result.setMsg(clazz.getName()+"枚举类中缺少所需getCode方法");
                    return result;
                } catch (InvocationTargetException | IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
            }

        }
        return result;
    }

}
